package net.qhzw.geologr5.gis.service.system.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.geologr5.gis.common.framework.utils.JsonResult;
import net.qhzw.geologr5.gis.common.framework.utils.StringUtils;
import net.qhzw.geologr5.gis.service.system.component.FileTemplate;
import net.qhzw.geologr5.gis.service.system.entity.Project;
import net.qhzw.geologr5.gis.service.system.entity.ProjectPoint;
import net.qhzw.geologr5.gis.service.system.exceltem.PointDrillingInfoExcel;
import net.qhzw.geologr5.gis.service.system.exceltem.PointProbeInfoExcel;
import net.qhzw.geologr5.gis.service.system.mapper.PointDrillingInfoMapper;
import net.qhzw.geologr5.gis.service.system.mapper.PointProbeInfoMapper;
import net.qhzw.geologr5.gis.service.system.mapper.ProjectMapper;
import net.qhzw.geologr5.gis.service.system.mapper.ProjectPointMapper;
import net.qhzw.geologr5.gis.service.system.query.ProjectPointQuery;
import net.qhzw.geologr5.gis.service.system.service.ProjectPointService;
import net.qhzw.geologr5.gis.service.system.utils.UUIDUtil;
import net.qhzw.geologr5.gis.service.system.vo.project.Point;
import net.qhzw.geologr5.gis.service.system.vo.project.PointDrillingInfoVo;
import net.qhzw.geologr5.gis.service.system.vo.project.PointProbeInfo;
import org.apache.poi.ss.usermodel.Workbook;
import org.csource.common.MyException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;


@Service
@Slf4j
public class ProjectPointServiceImpl implements ProjectPointService {

    @Autowired
    private ProjectPointMapper projectPointMapper;


    @Autowired
    private FileTemplate fileTemplate;

    @Autowired
    private PointProbeInfoMapper probeInfoMapper;

    @Autowired
    private PointDrillingInfoMapper drillingInfoMapper;

    @Autowired
    private ProjectMapper projectMapper;

    /***
     * 项目点位 新增修改
     * @param point
     * @param drillingInfoVo
     * @param probeInfo
     * @return
     */
    @Override
    @Transactional
    public JsonResult create(Point point, PointDrillingInfoVo drillingInfoVo,
                             PointProbeInfo probeInfo) {
        try {
            Integer pointType = point.getPointType();
            if (pointType == null || pointType <= 0) {
                return JsonResult.error("点位类型null");
            }
            if (StringUtils.isEmpty(point.getId())) {
                //添加操作
                String uUid = UUIDUtil.getUUid();
                ProjectPoint projectPoint = new ProjectPoint();
                projectPoint.setCreateTime(new Date());
                BeanUtils.copyProperties(point, projectPoint);
                if (point.getYears() == null) {
                    projectPoint.setYears(new Date());
                }
                if (pointType == 1) {
                    drillingInfoVo.setPointId(uUid);
                    drillingInfoVo.setDetailsId(UUIDUtil.getUUid());
                    drillingInfoMapper.insert(drillingInfoVo);
                    log.info("项目点位新增修改 1:钻孔信息 ==ProjectPointServiceImpl==method:create==drillingInfoVo: {}", JSON.toJSONString(drillingInfoVo));
                }
                if (pointType == 2) {
                    probeInfo.setPointId(uUid);
                    probeInfo.setDetailsId(UUIDUtil.getUUid());
                    probeInfoMapper.insert(probeInfo);
                    log.info("项目点位新增修改 2:探槽信息 ==ProjectPointServiceImpl==method:create==probeInfo: {}", JSON.toJSONString(probeInfo));
                }
                projectPoint.setId(uUid);
                int row = projectPointMapper.insert(projectPoint);
                return this.result(row, "添加失败");
            }
            ProjectPoint projectPoint = new ProjectPoint();
            BeanUtils.copyProperties(point, projectPoint);
            //查询原来的 删除 在新增
            String pointId = point.getId();
            ProjectPoint projectPoint1 = projectPointMapper.selectPointById(pointId);
            Integer pointType1 = projectPoint1.getPointType();
            //删除点位类型
            if (pointType1 == 1) {
                int row = drillingInfoMapper.deleteByPointId(pointId);
                if (row <= 0) {
                    return JsonResult.error("修改失败");
                }
            }
            if (pointType1 == 2) {
                int row = probeInfoMapper.deleteByPointId(pointId);
                if (row <= 0) {
                    return JsonResult.error("修改失败");
                }
            }

            //新增点位类型
            if (pointType == 1) {
                drillingInfoVo.setPointId(pointId);
                drillingInfoMapper.insert(drillingInfoVo);
            }
            if (pointType == 2) {
                probeInfo.setPointId(pointId);
                probeInfoMapper.insert(probeInfo);
            }
            int row = projectPointMapper.updateById(projectPoint);
            return this.result(row, "修改失败");
        } catch (Exception e) {
            log.error("项目点位新增修改==ProjectPointServiceImpl==method:create==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 删除点位
     * @param ids
     * @return
     */
    @Override
    public JsonResult delete(String[] ids) {
        try {
            List<String> idList = Arrays.asList(ids);
            int count = projectPointMapper.deleteBatchIds(idList);
            if (count > 0) {
                return JsonResult.success();
            }
            return JsonResult.error();
        } catch (Exception e) {
            log.error("删除点位失败==ProjectPointServiceImpl==method:delete==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     *  查询点位信息
     * @return
     */
    @Override
    public JsonResult find(ProjectPointQuery query) {
        PageHelper.startPage(query.getPage(), query.getLimit());
        Map<String, Object> result = new HashMap<>();
        try {
            if (query.getProjectId() == null || query.getProjectId() <= 0) {
                return JsonResult.error("查询参数null");
            }
            List<ProjectPoint> projectPointList = projectPointMapper.selectProjectPoint(query.getProjectId());
            for (ProjectPoint projectPoint : projectPointList) {
                Integer pointType = projectPoint.getPointType();
                if (pointType == 1) {
                    PointDrillingInfoVo drillingInfoVo = drillingInfoMapper.selectByPoinId(projectPoint.getId());
                    projectPoint.setDrillingInfoVo(drillingInfoVo);
                }
                if (pointType == 2) {
                    PointProbeInfo probeInfo = probeInfoMapper.selectByPoinId(projectPoint.getId());
                    projectPoint.setProbeInfo(probeInfo);
                }
            }
            log.info("查询点位信息==ProjectPointServiceImpl==method:find==projectPointList: {}", JSON.toJSONString(projectPointList));
            PageInfo<ProjectPoint> pageInfo = new PageInfo<>(projectPointList);
            result.put("total", pageInfo.getTotal());
            result.put("list", pageInfo.getList());
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("查询点位信息失败==ProjectPointServiceImpl==method:find==errMsg{}, ", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 项目点位图片下载
     * @param id
     * @param id
     * @return
     */
    @Override
    public JsonResult download(String id) {
        try {
            ProjectPoint projectPoint = projectPointMapper.selectPointById(id);
            log.info("项目点位图片下载==ProjectPointServiceImpl==method:download==projectPoint: {}", JSON.toJSONString(projectPoint));
            if (!StringUtils.isEmpty(projectPoint.getFile())) {
                String imgPath = projectPoint.getFile();
                if (StringUtils.isEmpty(imgPath)) {
                    return JsonResult.error("请上传后重试");
                }
                return JsonResult.success(imgPath, "SUCCESS");
            }
            return JsonResult.error("文件不存在");
        } catch (Exception e) {
            log.error("项目点位图片下载失败==ProjectPointServiceImpl==method:download==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 点位信息
     * @param query
     * @return
     */
    @Override
    public JsonResult pointInfo(ProjectPointQuery query) {
        try {
            Integer pointType = query.getPointType();
            if (pointType == null || pointType <= 0) {
                return JsonResult.error("点位类型null");
            }
            if (pointType == 1) {
                PointDrillingInfoVo drillingInfo = drillingInfoMapper.selectByPoinId(query.getPointId());
                return JsonResult.success(drillingInfo);
            }
            if (pointType == 2) {
                PointProbeInfo probeInfo = probeInfoMapper.selectByPoinId(query.getPointId());
                return JsonResult.success(probeInfo);
            }
            return JsonResult.error();
        } catch (Exception e) {
            log.error("点位信息查询失败==ProjectPointServiceImpl==method:pointInfo==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }

    }


    /***
     * 下载点位模板
     * @param param
     * @return
     */
    @Override
    public JsonResult downloadTmpl(String param, HttpServletResponse response) {
        Workbook workbook = null;
        FileOutputStream outputStream = null;
        try {
            //孔位信息
            if ("1".equals(param)) {
                List<PointDrillingInfoExcel> list = getPointDrillingInfo("1");
                workbook = ExcelExportUtil.exportExcel(new ExportParams("点位钻孔信息", "点位钻孔"),
                        PointDrillingInfoExcel.class, list);

            } else if ("2".equals(param)) {
                //探槽信息
                List<PointProbeInfoExcel> list = getPointDrillingInfo("2");
                workbook = ExcelExportUtil.exportExcel(new ExportParams("探槽信息信息", "探槽信息"),
                        PointProbeInfoExcel.class, list);
            } else {
                return JsonResult.error("参数有误");
            }
            //准备将Excel的输出流通过response输出到页面下载
            response.setContentType("application/octet-stream");
            if ("1".equals(param)) {
                response.setHeader("Content-disposition",
                        "attachment;filename=" + URLEncoder.encode("点位钻孔信息.xls", "UTF-8"));
            } else if ("2".equals(param)) {
                response.setHeader("Content-disposition",
                        "attachment;filename=" + URLEncoder.encode("探槽信息信息.xls", "UTF-8"));
            }
            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            workbook.write(response.getOutputStream());
            return JsonResult.success();
        } catch (Exception e) {
            System.out.println("IOException: " + e.getMessage());
            return JsonResult.error(e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /***
     * 导入点位模板
     * @param file
     * @return
     */
    @Override
    public JsonResult impexp(Integer projectId, String type, MultipartFile file) {
        log.info("文件名称: [{}]", file.getOriginalFilename());
        ImportParams params = new ImportParams();
        params.setTitleRows(1);//设置一级标题行为1行
        params.setHeadRows(1);//设置header标题为1行
        params.setStartRows(1);
        try {
            Project project = projectMapper.selectById(projectId);
            if (project == null) {
                return JsonResult.error("projectId 参数有误");
            }
            //点位钻孔信息
            if ("1".equals(type)) {
                List<PointDrillingInfoExcel> pointDrillings = ExcelImportUtil.importExcel(file.getInputStream(),
                        PointDrillingInfoExcel.class, params);
                //生成流水号
                String serlNum = getSerlNum("1");
                for (int i = 0; i < pointDrillings.size(); i++) {
                    PointDrillingInfoExcel pointDrilling = pointDrillings.get(i);
                    if (pointDrilling != null && pointDrilling.toString().length() > 240) {
                        ProjectPoint projectPoint = new ProjectPoint();
                        String uUid = UUIDUtil.getUUid();
                        projectPoint.setId(uUid);
                        if (pointDrilling.getYears() != null) {
                            projectPoint.setYears(pointDrilling.getYears());
                        } else {
                            projectPoint.setYears(new Date());
                        }
                        if (pointDrilling.getPtCoord() != null && !StringUtils.isEmpty(pointDrilling.getPtCoord())) {
                            projectPoint.setCoordinate(pointDrilling.getPtCoord());
                        }
                        if (pointDrilling.getPtDescr() != null && !StringUtils.isEmpty(pointDrilling.getPtDescr())) {
                            projectPoint.setDescribes(pointDrilling.getPtDescr());
                        }
                        projectPoint.setPointType(1);
                        projectPoint.setProjectId(projectId);
                        projectPoint.setCreateTime(new Date());
                        projectPointMapper.insert(projectPoint);
                        PointDrillingInfoVo drillingInfoVo = new PointDrillingInfoVo();
                        BeanUtils.copyProperties(pointDrilling, drillingInfoVo);
                        Long aLong = Long.valueOf(serlNum) + 1 + i;
                        drillingInfoVo.setDrillingNum(String.valueOf(aLong));
                        drillingInfoVo.setPointId(uUid);
                        drillingInfoVo.setDetailsId(UUIDUtil.getUUid());
                        if (project.getFileNumber() != null && !StringUtils.isEmpty(project.getFileNumber())) {
                            drillingInfoVo.setElectronicFileNum(project.getFileNumber());
                        }
                        drillingInfoMapper.insert(drillingInfoVo);
                    } else {
                        continue;
                    }

                }
            } else if ("2".equals(type)) {
                List<PointProbeInfoExcel> probeInfoExcels = ExcelImportUtil.importExcel(file.getInputStream(),
                        PointProbeInfoExcel.class, params);
                //生成流水号
                String serlNum = getSerlNum("2");
                for (int i = 0; i < probeInfoExcels.size(); i++) {
                    PointProbeInfoExcel probeInfo = probeInfoExcels.get(i);
                    if (probeInfo != null && probeInfo.toString().length() > 180) {
                        Long aLong = Long.valueOf(serlNum) + 1 + i;
                        ProjectPoint projectPoint = new ProjectPoint();
                        String uUid = UUIDUtil.getUUid();
                        projectPoint.setId(uUid);

                        if (probeInfo.getYears() != null) {
                            projectPoint.setYears(probeInfo.getYears());
                        } else {
                            projectPoint.setYears(new Date());
                        }
                        if (probeInfo.getPtDescr() != null && !StringUtils.isEmpty(probeInfo.getPtDescr())) {
                            projectPoint.setDescribes(probeInfo.getPtDescr());
                        }
                        if (probeInfo.getPtCoord() != null && !StringUtils.isEmpty(probeInfo.getPtCoord())) {
                            projectPoint.setCoordinate(probeInfo.getPtCoord());
                        }
                        projectPoint.setPointType(2);
                        projectPoint.setProjectId(projectId);
                        projectPoint.setCreateTime(new Date());
                        projectPointMapper.insert(projectPoint);
                        PointProbeInfo pointProbeInfo = new PointProbeInfo();
                        BeanUtils.copyProperties(probeInfo, pointProbeInfo);
                        pointProbeInfo.setSlotNum(String.valueOf(aLong));
                        pointProbeInfo.setPointId(uUid);
                        pointProbeInfo.setDetailsId(UUIDUtil.getUUid());
                        if (project.getFileNumber() != null && !StringUtils.isEmpty(project.getFileNumber())) {
                            pointProbeInfo.setElectronicFileNum(project.getFileNumber());
                        }
                        probeInfoMapper.insert(pointProbeInfo);
                    }

                }
            }

        } catch (Exception e) {
            return JsonResult.error(e.getMessage());
        }
        return JsonResult.success();
    }


    /***
     * 上传点位文件
     * @param id
     * @param file
     * @return
     */
    @Override
    public JsonResult uploadFile(String id, MultipartFile file) {
        try {
            ProjectPoint projectPoint = projectPointMapper.selectPointById(id);
            if (projectPoint == null) {
                return JsonResult.error("点位id有误");
            }

            String fileUrl = fileTemplate.fileUpload(file);
            if (fileUrl != null && !StringUtils.isEmpty(fileUrl)) {
                projectPoint.setFile(fileUrl);
            }
            int row = projectPointMapper.updateById(projectPoint);
            return JsonResult.result(row, "上传点位文件失败");
        } catch (Exception e) {
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 实例数据
     * @return
     */
    private List getPointDrillingInfo(String type) {
        if ("1".equals(type)) {
            //孔位信息
            List<PointDrillingInfoExcel> list = new ArrayList<>();
            PointDrillingInfoExcel poin = new PointDrillingInfoExcel();
            poin.setYears(new Date());
            poin.setPtCoord("x=222.66,y=777.99");
            poin.setCoordX(1112.33);
            poin.setCoordY(123.2);
            poin.setOpeningDt(new Date());
            poin.setEndHoleDt(new Date());
            poin.setDrillingAzimuth(123.67);
            poin.setDrillingAngle(234.12);
            poin.setFnlHoleDepth(283.34);
            poin.setDriSeesSituation("钻孔见矿情况");
            poin.setPtDescr("第一条数据为示例数据，请勿删除！请按照示例数据进行填写");
            list.add(poin);
            return list;
        } else if ("2".equals(type)) {
            //探槽信息
            List<PointProbeInfoExcel> list = new ArrayList<>();
            PointProbeInfoExcel poin = new PointProbeInfoExcel();
            poin.setYears(new Date());
            poin.setPtCoord("x=222.66,y=777.99");
            poin.setProbeSketch("探槽素描");
            poin.setPtCoordinateX(111.2);
            poin.setPtCoordinateY(222.3);
            poin.setElevationH(1232.2);
            poin.setScal("1:50");
            poin.setAzimuth(213.23);
            poin.setLenThegroove(21321.23);
            poin.setPtDescr("第一条数据为示例数据，请勿删除！请按照示例数据进行填写");
            list.add(poin);
            return list;
        }
        return null;
    }


    /****
     * 返回流水号 serlNum
     *          2021081200200
     * @return
     */
    private String getSerlNum(String type) {
        String serlNumMax = getTimeStr();
        if ("1".equals(type)) {
            serlNumMax = drillingInfoMapper.selectSerlNumMax();
        } else if ("2".equals(type)) {
            serlNumMax = probeInfoMapper.selectSerlNumMax();
        } else {
            return serlNumMax;
        }
        String uid_pfix = getTimeStr();
        String max_code = serlNumMax;
        String comment_code = "";
        if (max_code != null && max_code.contains(uid_pfix)) {
            String uid_end = max_code.substring(8, max_code.length());
            //吧String类型00011 转化为int的1
            int endNum = Integer.parseInt(uid_end);
            //结果为100002
            int tmpNum = 100000 + endNum + 1;
            //把100002首为1去掉
            comment_code = uid_pfix + subStr("" + tmpNum, 1);
        } else {
            comment_code = uid_pfix + "00001";
        }
        return comment_code;
    }

    /***
     * 把100002的首尾1去掉的方法
     * @param str
     * @param start
     * @return
     */
    private String subStr(String str, int start) {
        if (str == null || str.equals("")) {
            return "";
        }
        if (start < str.length()) {
            return str.substring(start);
        } else {
            return "";
        }
    }

    private String getTimeStr() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(new Date());
    }


    /***
     * 返回信息
     * @param row
     * @param message
     * @return
     */
    private JsonResult result(Integer row, String message) {
        if (row > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.error(message);
        }
    }


}
